﻿using System.Reflection;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;

namespace MetadataDesignerLibrary
{
    public class ExportedTypeRule : ILRule<ExportedTypeHandle>
    {
        [ILInfo]
        public TypeAttributes Attributes { get; }

        [ILInfo(true)]
        public string Namespace { get; }

        [ILInfo(true)]
        public string Name { get; }

        [ILInfo(true)]
        public EntityHandle Implementation { get; }

        [ILInfo]
        public int TypeDefinitionId { get; }

        [ILInfo]
        public bool IsForwarder { get; }

        public NamespaceDefinitionHandle NamespaceDefinition { get; }

        [ILInfo(ILInfoParseMethod.AsEntityHandleCollection)]
        public CustomAttributeHandleCollection CustomAttributes { get; }

        public ExportedTypeRule(
            TypeAttributes attributes,
            string @namespace,
            string name,
            EntityHandle implementation,
            int typeDefinitionId)
            : base()
        {
            Attributes = attributes;
            Namespace = @namespace;
            Name = name;
            Implementation = implementation;
            TypeDefinitionId = typeDefinitionId;
        }

        public ExportedTypeRule(MetadataReader reader, ExportedTypeHandle exportedTypeHandle)
            : base(reader)
        {
            ExportedType exportedType = reader.GetExportedType(exportedTypeHandle);
            Attributes = exportedType.Attributes;
            Implementation = exportedType.Implementation;
            IsForwarder = exportedType.IsForwarder;
            Name = reader.GetString(exportedType.Name);
            Namespace = reader.GetString(exportedType.Namespace);
            NamespaceDefinition = exportedType.NamespaceDefinition;
            CustomAttributes = exportedType.GetCustomAttributes();
        }

        public override ExportedTypeHandle Write(MetadataDesigner designer)
        {
            MetadataBuilder builder = designer.Builder;
            return builder.AddExportedType(
                attributes: Attributes,
                @namespace: Namespace == null ? default : builder.GetOrAddString(Namespace),
                name: Name == null ? default : builder.GetOrAddString(Name),
                implementation: Implementation,
                typeDefinitionId: TypeDefinitionId);
        }
    }
}